# Trabalho Assembly
#
# Implementação de LISTA DINAMICA
#
#Alunos: Kelyane W. Goncalves RA 67492
#Luiz …. RA …..



# Para gerar o executavel, gere primeiro o objeto executando
# o seguinte comando:
#
# as pratica.s -o pratica14.o
#
# e depois link dinamicamente com o seguinte comando:
#
# ld pratica14.o -l c -dynamic-linker /lib/ld-linux.so.2 -o pratica14


.section .data


# definicao das mensagens do programa

titgeral: 	.asciz		"\n*** APLICACAO DE Lista ***\n\n"
titemp: 	.asciz 		"\nAdicionando na lista:\n"
titdesemp:	.asciz		"\nRemovendo:\n"
titmostra:	.asciz		"\nElementos da Lista: \n"
titreg:		.asciz		"\nRegistro nº %d:"

menu:		.asciz		"\n\n\nOpções:\n1-Inserir\n2-Excluir\n3-Buscar\n4-Mostrar\n5-Fim\n> "

msgerro:	.asciz		"\nOpcao Incorreta!\n"
msgvazia:	.asciz		"\nFila Vazia!\n"
msgremov:	.asciz		"\nRegistro Removido!\n"
msginser:	.asciz		"\nRegistro Inserido!\n"
msgnot	:	.asciz		"\nRA não encontrado\n"

pedera:		.asciz		"Digite o ra: "
pedenome:	.asciz		"Digite o nome: "
pederg:		.asciz		"Digite o rg: "
pedecpf:	.asciz		"Digite o cpf: "
pedecurso:	.asciz		"Digite o curso: "
pedeano:	.asciz		"Digite o ano de ingresso:"
pedeendereco:	.asciz		"Digite o endereço: "
pedetelefone: 	.asciz		"Digite o telefone: "

# Para a função Mostra Lista

mostrara:	.asciz		"\nRA:	%d"
mostranome:	.asciz		"\nNome: %s"
mostrarg:	.asciz		"\nRG: %s"
mostracpf:	.asciz		"\nCPF: %s"
mostracurso:	.asciz		"\nCurso: %s"
mostraano:	.asciz		"\nAno: %s"
mostraendereco:	.asciz		"\nEndereco: %s"
mostratelefone:	.asciz		"\nTelefone: %s"

formastr:	.asciz		"%s"
formach:	.asciz		"%c"
formanum:	.asciz		"%d"

# variáveis de controle da Lista

inicio:		.int 0
final:		.int 0
quantidade:	.int 0

opcao:		.int 0

# variáveis que compões o registro

ra:		.int		0	
nome:		.space  	44	
rg:		.space		20
cpf:		.space		24
curso:		.space 		20
ano:		.space		12	
endereco:	.space		44	
telefone:	.space		24
prox:		.int 		0

naloc:		.int 196


.section	.text


.globl		main


main:
	jmp 	Inicio


####### INSERCAO	
	
# Durante a inserção podem ocorrer quatro hipóteses:
# 1- O Registro é o primeiro a ser inserido: Primeirainsercao
# 2- Insere o Registro no início da Lista: Insereinicio
# 3- Insere o Registro no meio da Lista: Inseremeio
# 4- Insere o Registro no final da Lista: Inserefinal
# Para tratar a inserção usa-se a função Insere, que verificará para qual siuação se encaixa

inserir:
	movl	inicio, %esi		# Joga Endereço do Início da Lista para %esi

	pushl 	$pedera
	call	printf
	
	pushl	$ra	
	pushl	$formanum
	call	scanf
	call	getchar

		
Primeirainsercao:
	movl	%esi, inicio		# a variável da lista recebe o endereço do primeiro registro
	
	movl	ra, %eax
	movl	%eax, (%esi)		# adiciona o valor do ra em (%esi)	

	addl	$192, %esi		# avança 192 bytes para atingir o ultimo elemento deste registro da lista
	movl	$final, %ebx		# Joga endereço de $final em %ebx
	movl	%ebx, (%esi)		# adiciona o ponteiro para o final da lista
	subl	$192, %esi		#volto para a proxima posição depois do ra e logo abaixo continua inserindo os dados

Continuainserindo:			
	addl 	$4, %esi

	pushl	$pedenome
	call	printf
	pushl	%esi
	call	gets
	addl	$44, %esi

	pushl	$pederg
	call	printf
	pushl	%esi
	call	gets
	addl	$20, %esi

	pushl	$pedecpf
	call	printf
	pushl	%esi
	call	gets
	addl	$24, %esi

	pushl	$pedecurso
	call	printf
	pushl	%esi
	call	gets
	addl	$20, %esi

	pushl	$pedeano
	call	printf
	pushl	%esi
	call	gets
	addl	$12, %esi

	pushl	$pedeendereco
	call	printf
	pushl	%esi
	call	gets
	addl	$44, %esi

	pushl	$pedetelefone
	call	printf
	pushl	%esi
	call	gets
	addl	$24, %esi

	incl	quantidade
	
	pushl	$msginser
	call	printf

	jmp	Menuinicial

	
####### BUSCAR UM ELEMENTO E IMPRIMIR	
buscar:
	movl	quantidade, %eax	# verifica quantos elementos tem na lista
	cmpl	$0, %eax		# se tiver 0 
	je	lista_vazia		# chama a lista vazia e da a mensagem de lista vazia
	
	pushl	$pedera			# se não vai pedi o RA
	call	printf
	pushl	$ra
	pushl	$formanum
	call	scanf
	movl	ra, %ebx		#comeca a busca do RA
	cmpl	$0, %ebx		#no comeco 
	movl	inicio, %esi		#da lista
	
continua_buscar:
	movl	ra, %eax		
	cmpl	(%esi), %eax		#se achar 
	je	mostra_elemento		#vai mostrar o elemento
	addl	$192, %esi		#se nao vai para o proximo
	movl	(%esi), %esi
	cmpl	%esi, final		#até encontrar ou chegar no fim da lista
	je	notFound		#se chegar no fim da lista o RA nao foi encontrado
	jmp	continua_buscar		#caminha na lista ate achar

mostra_elemento:			#achei o RA entao imprime o elemento
	pushl	(%esi)
	pushl	$mostrara
	call	printf
	addl	$4, %esi

	pushl	%esi
	pushl	$mostranome
	call	printf
	addl	$44, %esi	
	
	pushl	%esi
	pushl	$mostrarg
	call	printf
	addl	$20, %esi

	pushl	%esi
	pushl	$mostracpf
	call	printf
	addl	$24, %esi

	pushl	%esi
	pushl	$mostracurso
	call	printf
	addl	$20, %esi

	pushl	%esi
	pushl	$mostraano
	call	printf
	addl	$12, %esi

	pushl	%esi
	pushl	$mostraendereco
	call	printf
	addl	$44, %esi

	pushl	%esi
	pushl	$mostratelefone
	call	printf
	addl	$24, %esi
	
	call	getchar
	
	jmp 	Menuinicial

	
####### EXCLUIR	
excluir:


####### MOSTRAR TODOS OS ELEMENTOS
mostrar:				#mostra todos os elementos da lista
	movl	quantidade, %ebx	
	cmpl	$0, %ebx		#compara se a quantidade de elementos 
	je	lista_vazia		#se a quantidade for 0 entao a lista esta vazia
	movl	inicio, %esi		#se nao vou para o inicio da lista
	
mostra_elementos_lista:			#comeco mostrando o primeiro elemento da lista
	pushl	(%esi)
	pushl	$mostrara
	call	printf
	addl	$4, %esi

	pushl	%esi
	pushl	$mostranome
	call	printf
	addl	$44, %esi	
	
	pushl	%esi
	pushl	$mostrarg
	call	printf
	addl	$20, %esi

	pushl	%esi
	pushl	$mostracpf
	call	printf
	addl	$24, %esi

	pushl	%esi
	pushl	$mostracurso
	call	printf
	addl	$20, %esi

	pushl	%esi
	pushl	$mostraano
	call	printf
	addl	$12, %esi

	pushl	%esi
	pushl	$mostraendereco
	call	printf
	addl	$44, %esi

	pushl	%esi
	pushl	$mostratelefone
	call	printf
	addl	$24, %esi
		
	movl	$final, %ebx
	cmpl	%ebx, (%esi)		#compara se o %esi esta na ultima posição da lista
	movl	(%esi), %esi		#avança para o próximo
	jne	mostra_elementos_lista	#se nao tiver no ultimo elemento da lista, vai para o proximo
	
	call	getchar			#assim que acabar já imprime o menu abaixo
	 
####### MENU INICIAL	 
Menuinicial:
	pushl	$menu		# Empilha mensagem da pilha
	call 	printf		# Imprime a mensagem
	
	pushl	$opcao		# Empilha variável que salvará a opção
	pushl	$formanum   	# Define a forma como sendo inteiro
	call	scanf		# Lê valor do teclado

	cmpl	$1, opcao
	jz	inserir
	cmpl	$2, opcao
	jz	excluir
	cmpl	$3, opcao
	jz	buscar
	cmpl	$4, opcao
	jz	mostrar
	cmpl	$5, opcao
	jz	fim

	pushl	$msgerro
	call	printf

	jmp 	Menuinicial

Inicio:
	pushl	$196
	call	malloc
	movl	%eax, inicio	
	jmp	Menuinicial
	
fim:	
	pushl	$0
	call	exit

####### AUXILIARES	
lista_vazia:
	pushl	$msgvazia
	call	printf
	call	getchar
	jmp	Menuinicial

notFound:
	pushl	$msgnot
	call	printf
	call	getchar
	jmp	Menuinicial


 
